package com.zbkj.client.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zbkj.client.service.MaterialService;
import com.zbkj.common.model.assets.Material;
import com.zbkj.common.model.client.workbench.VideoTemplateFinal;
import com.zbkj.common.request.client.MaterialAddRequest;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.utils.OssUtil;
import com.zbkj.client.dao.MaterialMapper;
import com.zbkj.common.vo.client.OssResponseVo;
import com.zbkj.common.vo.client.CreateFolderVo;
import com.zbkj.client.vo.FileResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
public class MaterialServiceImpl implements MaterialService {

    @Autowired
    private MaterialMapper materialMapper;

    @Override
    public Material addMaterial(MaterialAddRequest request, Integer userId, Integer merId) {
        Material material = new Material();
        material.setName(request.getName());
        material.setIsFolder(request.getIsFolder());
        material.setIsDel(0);
        material.setParentId(request.getParentId() == null ? 0 : request.getParentId());
        material.setCreateTime(new Date());
        material.setUpdateTime(new Date());
        material.setUserId(userId);
        material.setMerId(merId);
        material.setDuration(request.getDuration());

        // 处理completeFolder
        String completeFolder = "/";
        if (material.getParentId() != null && material.getParentId() != 0) {
            Material parent = materialMapper.selectById(material.getParentId());
            if (parent == null) throw new CrmebException("父级文件夹不存在");
            completeFolder = parent.getCompleteFolder() + parent.getId() + "/";
        }
        material.setCompleteFolder(completeFolder);

        if (request.getIsFolder() != null && request.getIsFolder() == 1) {
            // 文件夹，直接插入
            materialMapper.insert(material);
            return material;
        }

        // 文件上传
        MultipartFile file = request.getFile();
        if (file != null && !file.isEmpty()){
            OssResponseVo upload = OssUtil.upload(file, userId, "material", merId);
            String url = upload.getUrl();
            material.setUrl(url);
            // 文件类型、后缀
            String originalFilename = file.getOriginalFilename();
            String fileTypeSuffix = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
            material.setFileTypeSuffix(fileTypeSuffix);
            material.setFileRealType(file.getContentType());
    //        material.setFileType(OssUtil.getFileType(fileTypeSuffix));
            materialMapper.insert(material);
            return material;
        }

        return null;
    }

    @Override
    public List<Material> listMaterial(Integer userId, Integer parentId) {
        QueryWrapper<Material> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("is_del", 0);
        if (parentId != null) {
            queryWrapper.eq("parent_id", parentId);
        }
        //TODO 是否共享权限补充
        return materialMapper.selectList(queryWrapper);
    }

    @Override
    public boolean createFolderOrMove(CreateFolderVo vo) {
        Integer userId = vo.getUserId();
        Integer merId = vo.getMerId();
        Integer parentId = vo.getParentId();
        String name = vo.getName();
        Integer id = vo.getId();

        // 重命名功能：name不为空且id不为空
        if (name != null && !name.isEmpty() && id != null) {
            Material material = materialMapper.selectById(id);
            if (material == null) throw new CrmebException("要重命名的文件夹不存在");
            //TODO 1
            if (material.getUserId() != userId) throw new CrmebException("您无权进行该操作");
            material.setName(name);
            material.setUpdateTime(new Date());
            materialMapper.updateById(material);
            return true;
        }

        // 移动文件夹：name为空且parentId不为空且id不为空
        if ((name == null || name.isEmpty()) && parentId != null && id != null) {
            Material folder = materialMapper.selectById(id);
            if (folder == null) throw new CrmebException("要移动的文件夹不存在");
            //TODO 2
            if (folder.getUserId() != userId) throw new CrmebException("您无权进行该操作");

            String completeFolderOld = folder.getCompleteFolder();
            String oldPath = completeFolderOld + id + "/";
            // 新父级
            Material parent = materialMapper.selectById(parentId);
            if (parent == null) throw new CrmebException("目标父级文件夹不存在");

            //TODO 2
            if (parent.getUserId() != userId) throw new CrmebException("您无权进行该操作");
            if (parent.getIsFolder() == 0) throw new CrmebException("请对文件夹进行操作");

            String completeFolderNew = parent.getCompleteFolder() + parent.getId() + "/";

            //TODO 3
            if (folder.getIsFolder() == 1){
                // 只有原文件是文件夹类型，才更新所有子文件夹和文件的complete_folder
                UpdateWrapper<Material> updateWrapper = new UpdateWrapper<>();
                updateWrapper.likeRight("complete_folder", oldPath);
                updateWrapper.setSql("complete_folder = CONCAT('" + completeFolderNew + id + "/', SUBSTRING(complete_folder, " + (oldPath.length() + 1) + "))");
                materialMapper.update(null, updateWrapper);
            }
            // 同时更新当前文件夹的parentId和complete_folder
            folder.setParentId(parentId);
            folder.setCompleteFolder(completeFolderNew);
            folder.setUpdateTime(new Date());
            materialMapper.updateById(folder);
            return true;
        }

        // 新建文件夹：id为空
        if (id == null) {
            Material material = new Material();
            material.setName(name);
            material.setParentId(parentId);
            material.setIsFolder(1);
            material.setIsDel(0);
            material.setUserId(userId);
            material.setMerId(merId);
            material.setCreateTime(new Date());
            material.setUpdateTime(new Date());
            // 处理completeFolder
            String completeFolder = "/";
            if (parentId != null && parentId != 0) {
                Material parent = materialMapper.selectById(parentId);
                if (parent == null) throw new CrmebException("父级文件夹不存在");

                //TODO 4
                if (parent.getUserId() != userId) throw new CrmebException("您无权进行该操作");
                completeFolder = parent.getCompleteFolder() + parent.getId() + "/";
            }
            material.setCompleteFolder(completeFolder);
            materialMapper.insert(material);
            return true;
        }

        return false;
    }

    //新建文件夹
    @Override
    public boolean createFolder(CreateFolderVo vo) {
        Integer userId = vo.getUserId();
        Integer merId = vo.getMerId();
        Integer parentId = vo.getParentId() == null ? 0 : vo.getParentId();
        String name = vo.getName();

        // 新建文件夹：id为空
        Material material = new Material();
        material.setName(name);
        material.setParentId(parentId);
        material.setIsFolder(1);
        material.setIsDel(0);
        material.setUserId(userId);
        material.setMerId(merId);
        material.setCreateTime(new Date());
        material.setUpdateTime(new Date());
        // 处理completeFolder
        String completeFolder = "/";
        if (parentId != null && parentId != 0) {
            Material parent = materialMapper.selectById(parentId);
            if (parent == null) throw new CrmebException("父级文件夹不存在");

            //TODO 4
            if (parent.getUserId() != userId) throw new CrmebException("您无权进行该操作");
            if (parent.getIsFolder() == 0) throw new CrmebException("不能移动到非文件夹下");

            completeFolder = parent.getCompleteFolder() + parent.getId() + "/";
        }
        material.setCompleteFolder(completeFolder);
        materialMapper.insert(material);
        return true;
    }

    @Override
    public boolean renameFile(CreateFolderVo vo) {
        Integer userId = vo.getUserId();
        String name = vo.getName();
        Integer id = vo.getId();

        if(name == null || name.isEmpty()) throw new CrmebException("请输入要改的名字");
        if(id == null || id == 0) throw new CrmebException("请选择要改名的文件");

        Material material = materialMapper.selectById(id);
        if (material == null) throw new CrmebException("要重命名的文件夹不存在");
        if (material.getUserId() != userId) throw new CrmebException("您无权进行该操作");

        material.setName(name);
        material.setUpdateTime(new Date());
        materialMapper.updateById(material);
        return true;
    }

    //移动文件夹
    @Override
    public boolean moveFolder(CreateFolderVo vo) {
        Integer userId = vo.getUserId();
        Integer merId = vo.getMerId();
        Integer parentId = vo.getParentId() == null ? 0 : vo.getParentId();

        Integer id = vo.getId();

        // 移动文件夹：name为空且parentId不为空且id不为空
        if(id == null) throw new CrmebException("请选择要移动的文件或者文件夹");

        Material folder = materialMapper.selectById(id);
        if (folder == null) throw new CrmebException("要移动的文件夹不存在");
        //TODO 2
        if (folder.getUserId() != userId) throw new CrmebException("您无权进行该操作");

        String completeFolderOld = folder.getCompleteFolder();
        String oldPath = completeFolderOld + id + "/";

        // 新父级
        String completeFolder = "/";
        if (parentId != 0) {
            Material parent = materialMapper.selectById(parentId);
            if (parent == null) throw new CrmebException("父级文件夹不存在");

            if (parent.getUserId() != userId) throw new CrmebException("您无权进行该操作");
            if (parent.getIsFolder() == 0) throw new CrmebException("请对文件夹进行操作");

            completeFolder = parent.getCompleteFolder() + parent.getId() + "/";
        }

        //TODO 3
        if (folder.getIsFolder() == 1){
            // 只有原文件是文件夹类型，才更新所有子文件夹和文件的complete_folder
            UpdateWrapper<Material> updateWrapper = new UpdateWrapper<>();
            updateWrapper.likeRight("complete_folder", oldPath);
            updateWrapper.setSql("complete_folder = CONCAT('" + completeFolder + id + "/', SUBSTRING(complete_folder, " + (oldPath.length() + 1) + "))");
            materialMapper.update(null, updateWrapper);
        }
        // 同时更新当前文件夹的parentId和complete_folder
        folder.setParentId(parentId);
        folder.setCompleteFolder(completeFolder);
        folder.setUpdateTime(new Date());
        materialMapper.updateById(folder);
        return true;
    }


    /**
     * 删除文件，同时将OSS地址设置到List
     * @param id
     * @param fileList
     * @return
     */
    private List<String> delMaterial(Integer id, List<String> fileList) {
        Material material = materialMapper.selectById(id);
        if (material == null) throw new CrmebException("素材不存在");
        // 判断是否为文件夹
        if (material.getIsFolder() != null && material.getIsFolder() == 1) {
            // 文件夹，删除所有子项
            String delFolderId = material.getCompleteFolder() + id + "/";
            UpdateWrapper<Material> updateWrapper = new UpdateWrapper<>();
            updateWrapper.likeRight("complete_folder", delFolderId);

            // 添加符合条件的is_folder=0记录的id到fileList
            List<Material> childItems = materialMapper.selectList(updateWrapper);
            for (Material childItem : childItems) {
                if (childItem.getIsFolder() != null && childItem.getIsFolder() == 0) {
                    if (childItem.getUrl() != null && !childItem.getUrl().isEmpty()) {
                        fileList.add(childItem.getUrl());
                    }
                }
            }

            updateWrapper.set("is_del", 1);
            materialMapper.update(null, updateWrapper);
        }else{
            if (material.getUrl() != null && !material.getUrl().isEmpty()) {
                fileList.add(material.getUrl());
            }
        }

        // 删除自身
        material.setIsDel(1);
        material.setUpdateTime(new Date());
        materialMapper.deleteById(material);
        return fileList;
    }

    @Override
    public boolean batchDelMaterial(List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }

        //要批量删除OSS文件，减少OSS删除文件的请求
        List<String> fileList = new ArrayList<>();
        
        for (Integer id : ids) {
            try {
                List<String> result = delMaterial(id, fileList);
                fileList = result;
            } catch (Exception e) {
                // 记录错误但继续处理其他ID
                log.error("删除素材ID " + id + " 失败: " + e.getMessage());
            }
        }

        //这里调用OSS的批量删除接口
        log.info("要删除的素材文件为：{}", fileList);
        // 如果列表不为空，异步删除OSS文件
        if (!fileList.isEmpty()) {
            final List<String> finalFileList = fileList;
            CompletableFuture.runAsync(() -> {
                try {
                    OssUtil.deleteMultiFileFromUrls(finalFileList);
                    log.info("异步删除素材OSS文件成功: {}", finalFileList);
                } catch (Exception e) {
                    log.error("异步删除素材OSS文件失败: {}, 错误信息: {}", finalFileList, e.getMessage());
                }
            });
        }

        return true;
    }

    @Override
    public Material getById(Integer id) {
        return materialMapper.selectById(id);
    }

    @Override
    public boolean batchMoveFolder(CreateFolderVo vo) {
        List<Integer> ids = vo.getIds();
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        
        Integer userId = vo.getUserId();
        Integer parentId = vo.getParentId();
        
        // 验证目标父级文件夹
        if (parentId != null && parentId != 0) {
            Material parent = materialMapper.selectById(parentId);
            if (parent == null) {
                throw new CrmebException("目标父级文件夹不存在");
            }
            if (!userId.equals(parent.getUserId())) {
                throw new CrmebException("无权操作目标文件夹");
            }
            if (parent.getIsFolder() == null || parent.getIsFolder() == 0) {
                throw new CrmebException("目标必须是文件夹");
            }
        }
        
        String completeFolderNew = "/";
        if (parentId != null && parentId != 0) {
            Material parent = materialMapper.selectById(parentId);
            completeFolderNew = parent.getCompleteFolder() + parent.getId() + "/";
        }
        
        for (Integer id : ids) {
            try {
                Material folder = materialMapper.selectById(id);
                if (folder == null) {
                    throw new CrmebException("文件夹ID " + id + " 不存在");
                }
                if (!userId.equals(folder.getUserId())) {
                    throw new CrmebException("无权操作文件夹ID " + id);
                }
                
                String completeFolderOld = folder.getCompleteFolder();
                String oldPath = completeFolderOld + id + "/";

                if (folder.getIsFolder() == 1){
                    // 更新所有子文件夹和文件的complete_folder
                    UpdateWrapper<Material> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.likeRight("complete_folder", oldPath);
                    updateWrapper.setSql("complete_folder = CONCAT('" + completeFolderNew + id + "/', SUBSTRING(complete_folder, " + (oldPath.length() + 1) + "))");
                    materialMapper.update(null, updateWrapper);
                }

                // 更新当前文件夹
                folder.setParentId(parentId);
                folder.setCompleteFolder(completeFolderNew);
                folder.setUpdateTime(new Date());
                materialMapper.updateById(folder);
                
            } catch (Exception e) {
                throw new CrmebException("移动文件夹ID " + id + " 失败: " + e.getMessage());
            }
        }
        
        return true;
    }

    @Override
    public Integer countMaterialByUserId(Integer userId) {
        QueryWrapper<Material> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", 0)
                   .eq("is_folder", 0)
                   .eq("user_id", userId);
        return materialMapper.selectCount(queryWrapper);
    }

    @Override
    public InputStream downloadFile(Integer fileId) {
        Material material = materialMapper.selectById(fileId);
        if (material == null || material.getIsDel() == null || material.getIsDel() != 0) {
            throw new CrmebException("文件不存在或已被删除");
        }
        
        if (material.getIsFolder() != null && material.getIsFolder() == 1) {
            throw new CrmebException("不能下载文件夹");
        }
        
        String url = material.getUrl();
        if (url == null || url.isEmpty()) {
            throw new CrmebException("文件URL为空");
        }
        
        // 使用OssUtil下载文件
        return OssUtil.downloadFileFromUrlAsStream(url);
    }

    @Override
    public FileResultVo getFileResultVoById(Integer id, Integer userId) {
        Material material = materialMapper.selectById(id);
        if (material == null || material.getIsDel() == null || material.getIsDel() != 0) {
            throw new CrmebException("素材文件不存在或已被删除");
        }
        if (!userId.equals(material.getUserId())) {
            throw new CrmebException("无权下载该素材文件");
        }
        if (material.getIsFolder() != null && material.getIsFolder() == 1) {
            throw new CrmebException("不能下载文件夹");
        }
        if (material.getUrl() == null || material.getUrl().isEmpty()) {
            throw new CrmebException("素材文件URL为空");
        }
        return new FileResultVo(material.getName(), material.getUrl());
    }
} 